package com.itmck.util;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 太阳当空照,花儿对我笑
 * <p>
 * Create by M ChangKe 2021/8/20 15:07
 **/
public class ReflectUtil {

    public static List<String> getEntityFieldList(Class<?> clazz) {

        ArrayList<Type> types = new ArrayList<>();
        ReflectUtil.getGenericTypes(types, clazz);
        try {
            Class<?> aClass = Class.forName(types.get(0).getTypeName());
            return Arrays.stream(aClass.getDeclaredFields())
                    .map(field -> {
                        if (field.isAnnotationPresent(TableId.class)) {
                            return field.getAnnotation(TableId.class).value();
                        }
                        if (field.isAnnotationPresent(TableField.class)) {
                            return field.getAnnotation(TableField.class).value();
                        }
                        return null;
                    })
                    .filter(StrUtil::isNotBlank)
                    .collect(Collectors.toList());

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return new ArrayList<>();

    }

    private static void getGenericTypes(ArrayList<Type> types, Class<?> clazz) {

        Type genericSuperclass = clazz.getGenericSuperclass();
        if (genericSuperclass instanceof ParameterizedType) {
            Collections.addAll(types, ((ParameterizedType) genericSuperclass).getActualTypeArguments());
        }
        Type[] genericInterfaces = clazz.getGenericInterfaces();
        for (Type genericInterface : genericInterfaces) {
            if (genericInterface instanceof ParameterizedType) {
                Collections.addAll(types, ((ParameterizedType) genericInterface).getActualTypeArguments());
            }
        }

        Class<?> superclass = clazz.getSuperclass();
        if (ObjectUtil.isNotNull(superclass)) {
            getGenericTypes(types, superclass);
        }
        Class<?>[] interfaces = clazz.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            getGenericTypes(types, anInterface);
        }

    }
}